#include <unistd.h>
#include"myshell.h"
#include<stdlib.h>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<string>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
//void Debug()
//{
//    printf("hello iu\n");
//}
//命令行参数表
char *gargv[ARGS]={NULL};
int gargc=0;
char pwd[1024];
int lastcode=0;


static std::string GetUserName()
{
    std::string username=getenv("USER");
    return username.empty()?"None":username;
}

static std::string GetHostName()
{
    std::string hostname=getenv("HOSTNAME");
    return hostname.empty()?"None":hostname;
}

static std::string GetPwd()
{
    //std::string pwd=getenv("PWD");
    //return pwd.empty()?"None":pwd;
    char temp[1024];
    getcwd(temp,sizeof(temp));
    snprintf(pwd,sizeof(pwd),"PWD=%s",temp);
    putenv(pwd);

    std::string pwd_label=temp;
    const std::string pathsep="/";
    auto pos=pwd_label.rfind(pathsep);
    if(pos==std::string::npos)
    {
        return "None";
    }

    pwd_label =pwd_label.substr(pos+1);
    return pwd_label.empty()?"/":pwd_label;
}

static std::string GetHomepwd()
{
    std::string home=getenv("HOME");
    return home.empty()?"None":home;
}

void PrintCommandPrompt()
{
    std::string user=GetUserName();
    std::string hostname=GetHostName();
    std::string pwd=GetPwd();
    printf("[%s@%s %s]",user.c_str(),hostname.c_str(),pwd.c_str());
}

bool GetCommandStr(char cmd_str_buff[],int len)
{
    if(cmd_str_buff==NULL||len<=0)
            return false;
    char *ret=fgets(cmd_str_buff,len,stdin);
    if(ret==NULL)
        return false;
    cmd_str_buff[strlen(cmd_str_buff)-1]=0;
    return strlen(cmd_str_buff)==0?false:true;
}

#define SEP " "
bool ParseCommandString(char cmd[])
{
    if(cmd==NULL)
        return false;
    gargv[gargc++]=strtok(cmd,SEP);
    while((bool)(gargv[gargc++]=strtok(NULL,SEP)));
    gargc--;

//#define DEBUG
#ifdef DEBUG 
    printf("gargc:%d\n",gargc);
    for(int i=0;i<gargc;i++)
    {
        printf("gargv[%d]:%s\n",i,gargv[i]);
    }
    for(int i=0;gargv[i];i++)
    {
        printf("gargv[%d]:%s\n",i,gargv[i]);
    }
#endif 

    return true;
}

void InitGargv()
{
    gargc=0;
    memset(gargv,0,sizeof(gargv));
}

void ForkAndExec()
{
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return;
    }
    else if(id==0)
    {
        execvp(gargv[0],gargv);
        exit(0);
    }
    else{
        int status=0;
        pid_t rid=waitpid(id,&status,0);
        if(rid>0)
        {
            lastcode=WEXITSTATUS(status);
        }
    }
}

bool BuiltInCommandExec()
{
    std::string cmd=gargv[0];
    bool ret=false;
    if(cmd=="cd")
    {
        if(gargc==2)
        {
            std::string target=gargv[1];
            if(target=="~")
            {
                ret=true;
                chdir(GetHomepwd().c_str());
            }
            else{
                ret=true;
                chdir(gargv[1]);
            }
        }
        else if(gargc==1)
        {
            ret=true;
            chdir(GetHomepwd().c_str());
        }
        else
        {
            
        }
    }
    else if(cmd=="echo")
    {
        if(gargc==2)
        {
            std::string args=gargv[1];
            if(args[0]=='$')
            {
                if(args[1]=='?')
                {
                    printf("lastcode:%d\n",lastcode);
                    ret=true;
                    lastcode=0;
                }
                else {
                    const char*name=&args[1];
                    printf("%s\n",getenv(name));
                    lastcode=0;
                    ret=true;
                }
            }
            else 
            {
                printf("%s\n",args.c_str());
                ret=true;
            }
        }
    }
    return ret;
}
